#region Microsoft Public License
/*
 * (c) Copyright Chenjun Wu. http://utablesdk.codeplex.com
 * 
 * This source is subject to the Microsoft Public License (Ms-PL).
 * Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
 * All other rights reserved.
 */
#endregion

﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Collections.Specialized;
using System.Collections.ObjectModel;

namespace UTable.Objects.Controls
{
    internal class UPanelImpl: ControlBaseImpl, IPanel
    {
        private Panel _owner;
        private ObservableUIElementCollection _children;

        private void OnChildrenChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    OnChildAdded(e.NewItems[0] as IControl, e.NewStartingIndex);
                    break;
                case NotifyCollectionChangedAction.Remove:
                    OnChildRemoved(e.OldItems[0] as IControl);
                    break;
                case NotifyCollectionChangedAction.Reset:
                    foreach (IVisualNode child in e.OldItems)
                        OnChildRemoved(child);
                    break;
                case NotifyCollectionChangedAction.Replace:
                    OnChildRemoved(e.OldItems[0] as IControl);
                    OnChildAdded(e.NewItems[0] as IControl, e.NewStartingIndex);
                    break;
                case NotifyCollectionChangedAction.Move:
                    break;
            }
            if (ChildrenChanged != null)
                ChildrenChanged(sender, e);
        }

        protected virtual void OnChildAdded(IVisualNode child, int startIndex)
        {
            if (child is IControl)
            {
                int offset = 0;
                for (int i = 0; i < startIndex; i++)
                {
                    if (!(_children[i] is IControl))
                        offset++;
                }
                startIndex -= offset;
                this.Info.Children.Insert(startIndex, (child as IControl).Info);
                (child as IControl).Info.Parent = this.Info;
            }
        }

        protected virtual void OnChildRemoved(IVisualNode child)
        {
            if (child is IControl)
            {
                this.Info.Children.Remove((child as IControl).Info);
                (child as IControl).Info.Parent = null;
            }
        }

        internal void OnVisualChildrenChanged(DependencyObject visualAdded, DependencyObject visualRemoved)
        {
            if (visualRemoved != null && visualRemoved is IControl)
            {
                OnChildRemoved(visualRemoved as IControl);
            }
            if (visualAdded != null && visualAdded is IControl)
            {
                OnChildAdded(visualAdded as IControl);
            }
        }

        private void OnChildAdded(IControl child)
        {
            int startIndex = _owner.Children.IndexOf(child as UIElement);
            int offset = 0;
            for (int i = 0; i < startIndex; i++)
            {
                if (!(_children[i] is IControl))
                    offset++;
            }
            startIndex -= offset;
            this.Info.Children.Insert(startIndex, (child as IControl).Info);
            (child as IControl).Info.Parent = this.Info;
        }

        private void OnChildRemoved(IControl child)
        {
            this.Info.Children.Remove((child as IControl).Info);
            (child as IControl).Info.Parent = null;
        }

        internal new static void OverrideMetadata(Type type)
        {
            ControlBaseImpl.OverrideMetadata(type);
            OverrideMetadata(Panel.BackgroundProperty, type);
        }

        internal UPanelImpl(Panel owner): base(owner)
        {
            _owner = owner;
            owner.Loaded += new RoutedEventHandler(owner_Loaded);
        }

        void owner_Loaded(object sender, RoutedEventArgs e)
        {
/*
            // reset all the children in the panel
            this.Info.Children.Clear();
            for (int i=0;i<_owner.Children.Count; i++)
            {
                OnChildAdded(_owner.Children[i] as IVisualNode, i);
            }*/

        }

        internal UIElementCollection CreateUIElementCollection(FrameworkElement logicalParent)
        {
            if (_children != null)
                _children.CollectionChanged -= OnChildrenChanged;
            _children = new ObservableUIElementCollection(_owner, logicalParent);
            // _children.CollectionChanged += OnChildrenChanged;
            return _children;
        }

        public new Collection<IControl> PanelChildren
        {
            get
            {
                Collection<IControl> children = new Collection<IControl>();
                foreach (UIElement child in _owner.Children)
                {
                    if (child != null && child is IControl)
                        children.Add(child as IControl);
                }
                return children;
            }
        }

        public event NotifyCollectionChangedEventHandler ChildrenChanged;
    }
}
